feat: Refactor EventEdit and EventFightList components for improved UI and functionality
All checks were successful
SteamWarCI Build successful

- Enhanced EventEdit component with AlertDialog for delete confirmation.
- Added Menubar component to EventFightList for batch editing options.
- Updated alert-dialog components to streamline props and improve reactivity.
- Refactored menubar components for better structure and usability.
- Improved accessibility and code readability across various components.
This commit is contained in:
2025-04-16 12:55:10 +02:00
parent 7757978668
commit 4da8fe50c0
23 changed files with 331 additions and 301 deletions

View File

@@ -3,19 +3,11 @@
import { buttonVariants } from "$lib/components/ui/button/index.js";
import { cn } from "$lib/components/utils.js";
type $$Props = AlertDialogPrimitive.ActionProps;
type $$Events = AlertDialogPrimitive.ActionEvents;
let className: $$Props["class"] = undefined;
export { className as class };
let {
ref = $bindable(null),
class: className,
...restProps
}: AlertDialogPrimitive.ActionProps = $props();
</script>
<AlertDialogPrimitive.Action
class={cn(buttonVariants(), className)}
{...$$restProps}
on:click
on:keydown
let:builder
>
<slot {builder} />
</AlertDialogPrimitive.Action>
<AlertDialogPrimitive.Action bind:ref class={cn(buttonVariants(), className)} {...restProps} />

View File

@@ -3,19 +3,15 @@
import { buttonVariants } from "$lib/components/ui/button/index.js";
import { cn } from "$lib/components/utils.js";
type $$Props = AlertDialogPrimitive.CancelProps;
type $$Events = AlertDialogPrimitive.CancelEvents;
let className: $$Props["class"] = undefined;
export { className as class };
let {
ref = $bindable(null),
class: className,
...restProps
}: AlertDialogPrimitive.CancelProps = $props();
</script>
<AlertDialogPrimitive.Cancel
bind:ref
class={cn(buttonVariants({ variant: "outline" }), "mt-2 sm:mt-0", className)}
{...$$restProps}
on:click
on:keydown
let:builder
>
<slot {builder} />
</AlertDialogPrimitive.Cancel>
{...restProps}
/>

View File

@@ -1,28 +1,26 @@
<script lang="ts">
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
import * as AlertDialog from "./index.js";
import { cn, flyAndScale } from "$lib/components/utils.js";
import { AlertDialog as AlertDialogPrimitive, type WithoutChild } from "bits-ui";
import AlertDialogOverlay from "./alert-dialog-overlay.svelte";
import { cn } from "$lib/components/utils.js";
type $$Props = AlertDialogPrimitive.ContentProps;
export let transition: $$Props["transition"] = flyAndScale;
export let transitionConfig: $$Props["transitionConfig"] = undefined;
let className: $$Props["class"] = undefined;
export { className as class };
let {
ref = $bindable(null),
class: className,
portalProps,
...restProps
}: WithoutChild<AlertDialogPrimitive.ContentProps> & {
portalProps?: AlertDialogPrimitive.PortalProps;
} = $props();
</script>
<AlertDialog.Portal>
<AlertDialog.Overlay />
<AlertDialogPrimitive.Portal {...portalProps}>
<AlertDialogOverlay />
<AlertDialogPrimitive.Content
{transition}
{transitionConfig}
bind:ref
class={cn(
"bg-background fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg sm:rounded-lg md:w-full",
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg",
className
)}
{...$$restProps}
>
<slot />
</AlertDialogPrimitive.Content>
</AlertDialog.Portal>
{...restProps}
/>
</AlertDialogPrimitive.Portal>

View File

@@ -2,15 +2,15 @@
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
import { cn } from "$lib/components/utils.js";
type $$Props = AlertDialogPrimitive.DescriptionProps;
let className: $$Props["class"] = undefined;
export { className as class };
let {
ref = $bindable(null),
class: className,
...restProps
}: AlertDialogPrimitive.DescriptionProps = $props();
</script>
<AlertDialogPrimitive.Description
bind:ref
class={cn("text-muted-foreground text-sm", className)}
{...$$restProps}
>
<slot />
</AlertDialogPrimitive.Description>
{...restProps}
/>

View File

@@ -1,16 +1,20 @@
<script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/components/utils.js";
type $$Props = HTMLAttributes<HTMLDivElement>;
let className: $$Props["class"] = undefined;
export { className as class };
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
class={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)}
{...$$restProps}
{...restProps}
>
<slot />
{@render children?.()}
</div>

View File

@@ -1,13 +1,20 @@
<script lang="ts">
import type { WithElementRef } from "bits-ui";
import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/components/utils.js";
type $$Props = HTMLAttributes<HTMLDivElement>;
let className: $$Props["class"] = undefined;
export { className as class };
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div class={cn("flex flex-col space-y-2 text-center sm:text-left", className)} {...$$restProps}>
<slot />
<div
bind:this={ref}
class={cn("flex flex-col space-y-2 text-center sm:text-left", className)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,21 +1,19 @@
<script lang="ts">
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
import { fade } from "svelte/transition";
import { cn } from "$lib/components/utils.js";
type $$Props = AlertDialogPrimitive.OverlayProps;
let className: $$Props["class"] = undefined;
export let transition: $$Props["transition"] = fade;
export let transitionConfig: $$Props["transitionConfig"] = {
duration: 150,
};
export { className as class };
let {
ref = $bindable(null),
class: className,
...restProps
}: AlertDialogPrimitive.OverlayProps = $props();
</script>
<AlertDialogPrimitive.Overlay
{transition}
{transitionConfig}
class={cn("bg-background/80 fixed inset-0 z-50 backdrop-blur-sm ", className)}
{...$$restProps}
bind:ref
class={cn(
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80",
className
)}
{...restProps}
/>

View File

@@ -2,13 +2,17 @@
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
import { cn } from "$lib/components/utils.js";
type $$Props = AlertDialogPrimitive.TitleProps;
let className: $$Props["class"] = undefined;
export let level: $$Props["level"] = "h3";
export { className as class };
let {
ref = $bindable(null),
class: className,
level = 3,
...restProps
}: AlertDialogPrimitive.TitleProps = $props();
</script>
<AlertDialogPrimitive.Title class={cn("text-lg font-semibold", className)} {level} {...$$restProps}>
<slot />
</AlertDialogPrimitive.Title>
<AlertDialogPrimitive.Title
bind:ref
class={cn("text-lg font-semibold", className)}
{level}
{...restProps}
/>

View File

@@ -1,9 +1,7 @@
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
import Title from "./alert-dialog-title.svelte";
import Action from "./alert-dialog-action.svelte";
import Cancel from "./alert-dialog-cancel.svelte";
import Portal from "./alert-dialog-portal.svelte";
import Footer from "./alert-dialog-footer.svelte";
import Header from "./alert-dialog-header.svelte";
import Overlay from "./alert-dialog-overlay.svelte";
@@ -12,6 +10,7 @@ import Description from "./alert-dialog-description.svelte";
const Root = AlertDialogPrimitive.Root;
const Trigger = AlertDialogPrimitive.Trigger;
const Portal = AlertDialogPrimitive.Portal;
export {
Root,

View File

@@ -1,10 +1,9 @@
import { Menubar as MenubarPrimitive } from "bits-ui";
import Root from "./menubar.svelte";
import CheckboxItem from "./menubar-checkbox-item.svelte";
import Content from "./menubar-content.svelte";
import Item from "./menubar-item.svelte";
import Label from "./menubar-label.svelte";
import GroupHeading from "./menubar-group-heading.svelte";
import RadioItem from "./menubar-radio-item.svelte";
import Separator from "./menubar-separator.svelte";
import Shortcut from "./menubar-shortcut.svelte";
@@ -22,7 +21,7 @@ export {
CheckboxItem,
Content,
Item,
Label,
GroupHeading,
RadioItem,
Separator,
Shortcut,
@@ -38,7 +37,7 @@ export {
CheckboxItem as MenubarCheckboxItem,
Content as MenubarContent,
Item as MenubarItem,
Label as MenubarLabel,
GroupHeading as MenubarGroupHeading,
RadioItem as MenubarRadioItem,
Separator as MenubarSeparator,
Shortcut as MenubarShortcut,

View File

@@ -1,35 +1,40 @@
<script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui";
import Check from "lucide-svelte/icons/check";
import { Menubar as MenubarPrimitive, type WithoutChildrenOrChild } from "bits-ui";
import Check from "@lucide/svelte/icons/check";
import Minus from "@lucide/svelte/icons/minus";
import { cn } from "$lib/components/utils.js";
import type { Snippet } from "svelte";
type $$Props = MenubarPrimitive.CheckboxItemProps;
type $$Events = MenubarPrimitive.CheckboxItemEvents;
let className: $$Props["class"] = undefined;
export let checked: $$Props["checked"] = false;
export { className as class };
let {
ref = $bindable(null),
class: className,
checked = $bindable(false),
indeterminate = $bindable(false),
children: childrenProp,
...restProps
}: WithoutChildrenOrChild<MenubarPrimitive.CheckboxItemProps> & {
children?: Snippet;
} = $props();
</script>
<MenubarPrimitive.CheckboxItem
bind:ref
bind:checked
bind:indeterminate
class={cn(
"data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className
)}
on:click
on:keydown
on:focusin
on:focusout
on:pointerleave
on:pointermove
on:pointerdown
{...$$restProps}
{...restProps}
>
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<MenubarPrimitive.CheckboxIndicator>
<Check class="h-4 w-4" />
</MenubarPrimitive.CheckboxIndicator>
</span>
<slot />
{#snippet children({ checked, indeterminate })}
<span class="absolute left-2 flex size-3.5 items-center justify-center">
{#if indeterminate}
<Minus class="size-4" />
{:else}
<Check class={cn("size-4", !checked && "text-transparent")} />
{/if}
</span>
{@render childrenProp?.()}
{/snippet}
</MenubarPrimitive.CheckboxItem>

View File

@@ -1,33 +1,32 @@
<script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn, flyAndScale } from "$lib/components/utils.js";
import { cn } from "$lib/components/utils.js";
type $$Props = MenubarPrimitive.ContentProps;
type $$Events = MenubarPrimitive.ContentEvents;
let className: $$Props["class"] = undefined;
export let sideOffset: $$Props["sideOffset"] = 8;
export let alignOffset: $$Props["alignOffset"] = -4;
export let align: $$Props["align"] = "start";
export let side: $$Props["side"] = "bottom";
export let transition: $$Props["transition"] = flyAndScale;
export let transitionConfig: $$Props["transitionConfig"] = undefined;
export { className as class };
let {
ref = $bindable(null),
class: className,
sideOffset = 8,
alignOffset = -4,
align = "start",
side = "bottom",
portalProps,
...restProps
}: MenubarPrimitive.ContentProps & {
portalProps?: MenubarPrimitive.PortalProps;
} = $props();
</script>
<MenubarPrimitive.Content
{transition}
{transitionConfig}
{sideOffset}
{align}
{alignOffset}
{side}
class={cn(
"bg-popover text-popover-foreground z-50 min-w-[12rem] rounded-md border p-1 shadow-md focus:outline-none",
className
)}
{...$$restProps}
on:keydown
>
<slot />
</MenubarPrimitive.Content>
<MenubarPrimitive.Portal {...portalProps}>
<MenubarPrimitive.Content
bind:ref
{sideOffset}
{align}
{alignOffset}
{side}
class={cn(
"bg-popover text-popover-foreground z-50 min-w-[12rem] rounded-md border p-1 shadow-md focus:outline-none",
className
)}
{...restProps}
/>
</MenubarPrimitive.Portal>

View File

@@ -0,0 +1,19 @@
<script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn } from "$lib/components/utils.js";
let {
ref = $bindable(null),
class: className,
inset = undefined,
...restProps
}: MenubarPrimitive.GroupHeadingProps & {
inset?: boolean;
} = $props();
</script>
<MenubarPrimitive.GroupHeading
bind:ref
class={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
{...restProps}
/>

View File

@@ -2,30 +2,22 @@
import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn } from "$lib/components/utils.js";
type $$Props = MenubarPrimitive.ItemProps & {
let {
ref = $bindable(null),
class: className,
inset = undefined,
...restProps
}: MenubarPrimitive.ItemProps & {
inset?: boolean;
};
type $$Events = MenubarPrimitive.ItemEvents;
let className: $$Props["class"] = undefined;
export let inset: $$Props["inset"] = undefined;
export { className as class };
} = $props();
</script>
<MenubarPrimitive.Item
bind:ref
class={cn(
"data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
inset && "pl-8",
className
)}
{...$$restProps}
on:click
on:keydown
on:focusin
on:focusout
on:pointerleave
on:pointermove
on:pointerdown
>
<slot />
</MenubarPrimitive.Item>
{...restProps}
/>

View File

@@ -1,35 +1,30 @@
<script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui";
import Circle from "lucide-svelte/icons/circle";
import { Menubar as MenubarPrimitive, type WithoutChild } from "bits-ui";
import Circle from "@lucide/svelte/icons/circle";
import { cn } from "$lib/components/utils.js";
type $$Props = MenubarPrimitive.RadioItemProps;
type $$Events = MenubarPrimitive.RadioItemEvents;
let className: $$Props["class"] = undefined;
export let value: $$Props["value"];
export { className as class };
let {
ref = $bindable(null),
class: className,
children: childrenProp,
...restProps
}: WithoutChild<MenubarPrimitive.RadioItemProps> = $props();
</script>
<MenubarPrimitive.RadioItem
{value}
bind:ref
class={cn(
"data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className
)}
{...$$restProps}
on:click
on:keydown
on:focusin
on:focusout
on:pointerleave
on:pointermove
on:pointerdown
{...restProps}
>
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<MenubarPrimitive.RadioIndicator>
<Circle class="h-2 w-2 fill-current" />
</MenubarPrimitive.RadioIndicator>
</span>
<slot />
{#snippet children({ checked })}
<span class="absolute left-2 flex size-3.5 items-center justify-center">
{#if checked}
<Circle class="size-2 fill-current" />
{/if}
</span>
{@render childrenProp?.({ checked })}
{/snippet}
</MenubarPrimitive.RadioItem>

View File

@@ -2,10 +2,15 @@
import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn } from "$lib/components/utils.js";
type $$Props = MenubarPrimitive.SeparatorProps;
let className: $$Props["class"] = undefined;
export { className as class };
let {
ref = $bindable(null),
class: className,
...restProps
}: MenubarPrimitive.SeparatorProps = $props();
</script>
<MenubarPrimitive.Separator class={cn("bg-muted -mx-1 my-1 h-px", className)} {...$$restProps} />
<MenubarPrimitive.Separator
bind:ref
class={cn("bg-muted -mx-1 my-1 h-px", className)}
{...restProps}
/>

View File

@@ -1,16 +1,20 @@
<script lang="ts">
import type { HTMLAttributes } from "svelte/elements";
import type { WithElementRef } from "bits-ui";
import { cn } from "$lib/components/utils.js";
type $$Props = HTMLAttributes<HTMLSpanElement>;
let className: $$Props["class"] = undefined;
export { className as class };
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLSpanElement>> = $props();
</script>
<span
bind:this={ref}
class={cn("text-muted-foreground ml-auto text-xs tracking-widest", className)}
{...$$restProps}
{...restProps}
>
<slot />
{@render children?.()}
</span>

View File

@@ -1,27 +1,19 @@
<script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn, flyAndScale } from "$lib/components/utils.js";
import { cn } from "$lib/components/utils.js";
type $$Props = MenubarPrimitive.SubContentProps;
type $$Events = MenubarPrimitive.SubContentEvents;
let className: $$Props["class"] = undefined;
export let transition: $$Props["transition"] = flyAndScale;
export let transitionConfig: $$Props["transitionConfig"] = { x: -10, y: 0 };
export { className as class };
let {
ref = $bindable(null),
class: className,
...restProps
}: MenubarPrimitive.SubContentProps = $props();
</script>
<MenubarPrimitive.SubContent
{transition}
{transitionConfig}
bind:ref
class={cn(
"bg-popover text-popover-foreground z-50 min-w-max rounded-md border p-1 focus:outline-none",
className
)}
{...$$restProps}
on:focusout
on:pointermove
on:keydown
>
<slot />
</MenubarPrimitive.SubContent>
{...restProps}
/>

View File

@@ -1,32 +1,28 @@
<script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui";
import ChevronRight from "lucide-svelte/icons/chevron-right";
import { Menubar as MenubarPrimitive, type WithoutChild } from "bits-ui";
import ChevronRight from "@lucide/svelte/icons/chevron-right";
import { cn } from "$lib/components/utils.js";
type $$Props = MenubarPrimitive.SubTriggerProps & {
let {
ref = $bindable(null),
class: className,
inset = undefined,
children,
...restProps
}: WithoutChild<MenubarPrimitive.SubTriggerProps> & {
inset?: boolean;
};
type $$Events = MenubarPrimitive.SubTriggerEvents;
let className: $$Props["class"] = undefined;
export let inset: $$Props["inset"] = undefined;
export { className as class };
} = $props();
</script>
<MenubarPrimitive.SubTrigger
bind:ref
class={cn(
"data-[highlighted]:bg-accent data-[state=open]:bg-accent data-[highlighted]:text-accent-foreground data-[state=open]:text-accent-foreground flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
inset && "pl-8",
className
)}
on:click
{...$$restProps}
on:keydown
on:focusin
on:focusout
on:pointerleave
on:pointermove
{...restProps}
>
<slot />
<ChevronRight class="ml-auto h-4 w-4" />
{@render children?.()}
<ChevronRight class="ml-auto size-4" />
</MenubarPrimitive.SubTrigger>

View File

@@ -2,22 +2,18 @@
import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn } from "$lib/components/utils.js";
type $$Props = MenubarPrimitive.TriggerProps;
type $$Events = MenubarPrimitive.TriggerEvents;
let className: $$Props["class"] = undefined;
export { className as class };
let {
ref = $bindable(null),
class: className,
...restProps
}: MenubarPrimitive.TriggerProps = $props();
</script>
<MenubarPrimitive.Trigger
bind:ref
class={cn(
"data-[highlighted]:bg-accent data-[state=open]:bg-accent data-[highlighted]:text-accent-foreground data-[state=open]:text-accent-foreground flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none",
className
)}
on:click
on:keydown
on:pointerenter
{...$$restProps}
>
<slot />
</MenubarPrimitive.Trigger>
{...restProps}
/>

View File

@@ -2,15 +2,15 @@
import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn } from "$lib/components/utils.js";
type $$Props = MenubarPrimitive.Props;
let className: $$Props["class"] = undefined;
export { className as class };
let {
ref = $bindable(null),
class: className,
...restProps
}: MenubarPrimitive.RootProps = $props();
</script>
<MenubarPrimitive.Root
bind:ref
class={cn("bg-background flex h-10 items-center space-x-1 rounded-md border p-1", className)}
{...$$restProps}
>
<slot />
</MenubarPrimitive.Root>
{...restProps}
/>