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

@ -18,24 +18,35 @@
-->
<script lang="ts">
import {Input} from "@components/ui/input";
import {Label} from "@components/ui/label";
import {Popover, PopoverContent, PopoverTrigger} from "@components/ui/popover";
import type {SWEvent} from "@type/event.ts"
import { Input } from "@components/ui/input";
import { Label } from "@components/ui/label";
import { Popover, PopoverContent, PopoverTrigger } from "@components/ui/popover";
import type { SWEvent } from "@type/event.ts";
import DateTimePicker from "@components/ui/datetime-picker/DateTimePicker.svelte";
import {fromAbsolute} from "@internationalized/date";
import {Button} from "@components/ui/button";
import {ChevronsUpDown} from "lucide-svelte";
import {Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList} from "@components/ui/command";
import {schemTypes} from "@stores/stores.ts";
import { fromAbsolute } from "@internationalized/date";
import { Button, buttonVariants } from "@components/ui/button";
import { ChevronsUpDown } from "lucide-svelte";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@components/ui/command";
import { schemTypes } from "@stores/stores.ts";
import Check from "lucide-svelte/icons/check";
import {cn} from "@components/utils.ts";
import {Switch} from "@components/ui/switch";
import {eventRepo} from "@repo/event.ts";
import { cn } from "@components/utils.ts";
import { Switch } from "@components/ui/switch";
import { eventRepo } from "@repo/event.ts";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@components/ui/alert-dialog";
const { event }: { event: SWEvent } = $props();
let rootEvent: SWEvent = $state(event)
let rootEvent: SWEvent = $state(event);
let eventName = $state(rootEvent.name);
let eventDeadline = $state(fromAbsolute(rootEvent.deadline, "Europe/Berlin"));
@ -45,13 +56,15 @@
let eventSchematicType = $state(rootEvent.schemType);
let eventPublicsOnly = $state(rootEvent.publicSchemsOnly);
let dirty = $derived(eventName !== rootEvent.name ||
eventDeadline.toDate().getTime() !== rootEvent.deadline ||
eventStart.toDate().getTime() !== rootEvent.start ||
eventEnd.toDate().getTime() !== rootEvent.end ||
eventTeamSize !== rootEvent.maxTeamMembers ||
eventSchematicType !== rootEvent.schemType ||
eventPublicsOnly !== rootEvent.publicSchemsOnly);
let dirty = $derived(
eventName !== rootEvent.name ||
eventDeadline.toDate().getTime() !== rootEvent.deadline ||
eventStart.toDate().getTime() !== rootEvent.start ||
eventEnd.toDate().getTime() !== rootEvent.end ||
eventTeamSize !== rootEvent.maxTeamMembers ||
eventSchematicType !== rootEvent.schemType ||
eventPublicsOnly !== rootEvent.publicSchemsOnly
);
async function updateEvent() {
rootEvent = await $eventRepo.updateEvent(event.id.toString(), {
@ -62,7 +75,7 @@
maxTeamMembers: eventTeamSize,
schemType: eventSchematicType,
publicSchemsOnly: eventPublicsOnly,
})
});
}
</script>
@ -81,13 +94,8 @@
<Popover>
<PopoverTrigger>
{#snippet child({ props })}
<Button
variant="outline"
class="justify-between"
{...props}
role="combobox"
>
{$schemTypes.find(value => value.db === eventSchematicType)?.name || eventSchematicType || "Select a schematic type..."}
<Button variant="outline" class="justify-between" {...props} role="combobox">
{$schemTypes.find((value) => value.db === eventSchematicType)?.name || eventSchematicType || "Select a schematic type..."}
<ChevronsUpDown class="ml-2 size-4 shrink-0 opacity-50" />
</Button>
{/snippet}
@ -100,17 +108,12 @@
<CommandGroup>
{#each $schemTypes as type}
<CommandItem
value={type.db}
onSelect={() => {
eventSchematicType = type.db;
}}
value={type.db}
onSelect={() => {
eventSchematicType = type.db;
}}
>
<Check
class={cn(
"mr-2 size-4",
eventSchematicType !== type.db && "text-transparent"
)}
/>
<Check class={cn("mr-2 size-4", eventSchematicType !== type.db && "text-transparent")} />
{type.name}
</CommandItem>
{/each}
@ -122,7 +125,19 @@
<Label for="event-publics">Publics Schematics Only</Label>
<Switch id="event-publics" bind:checked={eventPublicsOnly} />
<div class="flex flex-row justify-end border-t pt-2 gap-4">
<Button variant="destructive">Delete</Button>
<AlertDialog>
<AlertDialogTrigger class={buttonVariants({ variant: "destructive" })}>Delete</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Are you sure?</AlertDialogTitle>
<AlertDialogDescription>This action cannot be undone.</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction disabled>Delete</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<Button disabled={!dirty} onclick={updateEvent}>Update</Button>
</div>
</div>
</div>

View File

@ -20,20 +20,11 @@
<script lang="ts">
import type { ExtendedEvent } from "@type/event";
import { createSvelteTable, FlexRender } from "@components/ui/data-table";
import {
type ColumnFiltersState,
getCoreRowModel,
getFilteredRowModel,
getGroupedRowModel,
getPaginationRowModel,
getSortedRowModel,
type GroupingState,
type RowSelectionState,
type SortingState,
} from "@tanstack/table-core";
import { type ColumnFiltersState, getCoreRowModel, getFilteredRowModel, getGroupedRowModel, getSortedRowModel, type RowSelectionState, type SortingState } from "@tanstack/table-core";
import { columns } from "./columns";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@components/ui/table";
import { Checkbox } from "@components/ui/checkbox";
import { Menubar, MenubarContent, MenubarItem, MenubarGroup, MenubarGroupHeading, MenubarMenu, MenubarSeparator, MenubarTrigger } from "@components/ui/menubar";
let { data }: { data: ExtendedEvent } = $props();
@ -93,6 +84,30 @@
});
</script>
<div class="w-fit">
<Menubar>
<MenubarMenu>
<MenubarTrigger>Mehrfach Bearbeiten</MenubarTrigger>
<MenubarContent>
<MenubarItem disabled>Gruppe Ändern</MenubarItem>
<MenubarItem disabled>Startzeit Verschieben</MenubarItem>
<MenubarItem disabled>Spectate Port Ändern</MenubarItem>
</MenubarContent>
</MenubarMenu>
<MenubarMenu>
<MenubarTrigger>Erstellen</MenubarTrigger>
<MenubarContent>
<MenubarItem disabled>Fight Erstellen</MenubarItem>
<MenubarGroup>
<MenubarGroupHeading>Generatoren</MenubarGroupHeading>
<MenubarItem disabled>Gruppenphase</MenubarItem>
<MenubarItem disabled>K.O. Phase</MenubarItem>
</MenubarGroup>
</MenubarContent>
</MenubarMenu>
</Menubar>
</div>
<Table>
<TableHeader>
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)}

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}
/>