Quillan-Ronin / llama.cpp /tools /server /webui /src /lib /components /app /navigation /DropdownMenuActions.svelte
| <script lang="ts"> | |
| import * as DropdownMenu from '$lib/components/ui/dropdown-menu'; | |
| import * as Tooltip from '$lib/components/ui/tooltip'; | |
| import { KeyboardShortcutInfo } from '$lib/components/app'; | |
| import type { Component } from 'svelte'; | |
| interface ActionItem { | |
| icon: Component; | |
| label: string; | |
| onclick: (event: Event) => void; | |
| variant?: 'default' | 'destructive'; | |
| disabled?: boolean; | |
| shortcut?: string[]; | |
| separator?: boolean; | |
| } | |
| interface Props { | |
| triggerIcon: Component; | |
| triggerTooltip?: string; | |
| triggerClass?: string; | |
| actions: ActionItem[]; | |
| align?: 'start' | 'center' | 'end'; | |
| open?: boolean; | |
| } | |
| let { | |
| triggerIcon, | |
| triggerTooltip, | |
| triggerClass = '', | |
| actions, | |
| align = 'end', | |
| open = $bindable(false) | |
| }: Props = $props(); | |
| </script> | |
| <DropdownMenu.Root bind:open> | |
| <DropdownMenu.Trigger | |
| class="flex h-6 w-6 cursor-pointer items-center justify-center rounded-md p-0 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[state=open]:bg-accent data-[state=open]:text-accent-foreground {triggerClass}" | |
| onclick={(e) => e.stopPropagation()} | |
| > | |
| {#if triggerTooltip} | |
| <Tooltip.Root> | |
| <Tooltip.Trigger> | |
| {@render iconComponent(triggerIcon, 'h-3 w-3')} | |
| <span class="sr-only">{triggerTooltip}</span> | |
| </Tooltip.Trigger> | |
| <Tooltip.Content> | |
| <p>{triggerTooltip}</p> | |
| </Tooltip.Content> | |
| </Tooltip.Root> | |
| {:else} | |
| {@render iconComponent(triggerIcon, 'h-3 w-3')} | |
| {/if} | |
| </DropdownMenu.Trigger> | |
| <DropdownMenu.Content {align} class="z-[999999] w-48"> | |
| {#each actions as action, index (action.label)} | |
| {#if action.separator && index > 0} | |
| <DropdownMenu.Separator /> | |
| {/if} | |
| <DropdownMenu.Item | |
| onclick={action.onclick} | |
| variant={action.variant} | |
| disabled={action.disabled} | |
| class="flex items-center justify-between hover:[&>kbd]:opacity-100" | |
| > | |
| <div class="flex items-center gap-2"> | |
| {@render iconComponent( | |
| action.icon, | |
| `h-4 w-4 ${action.variant === 'destructive' ? 'text-destructive' : ''}` | |
| )} | |
| {action.label} | |
| </div> | |
| {#if action.shortcut} | |
| <KeyboardShortcutInfo keys={action.shortcut} variant={action.variant} /> | |
| {/if} | |
| </DropdownMenu.Item> | |
| {/each} | |
| </DropdownMenu.Content> | |
| </DropdownMenu.Root> | |
| {#snippet iconComponent(IconComponent: Component, className: string)} | |
| <IconComponent class={className} /> | |
| {/snippet} | |