DropdownMenu

This commit is contained in:
Diego Imbert
2026-02-06 15:36:41 +01:00
parent d230b52cf9
commit 2bd0e18154
4 changed files with 61 additions and 6 deletions
@@ -0,0 +1,31 @@
<script lang="ts">
type Item = {
label: string
icon?: any
onClick: () => void
}
type Props = {
closeCallback?: () => void
items: Item[]
}
let { items, closeCallback }: Props = $props()
</script>
<ul class="bg-surface-tertiary rounded-md border w-48 relative drop-shadow-base">
{#each items as item}
<li class="w-full">
<button
class="px-3 h-9 text-xs cursor-pointer hover:bg-surface-hover font-normal w-full text-left flex items-center gap-2.5"
onclick={() => {
item.onClick()
closeCallback?.()
}}
>
{#if item.icon}
<item.icon size="16"></item.icon>
{/if}
{item.label}
</button>
</li>
{/each}
</ul>
@@ -2,6 +2,13 @@
import { clickOutside } from '$lib/utils'
import { fly } from 'svelte/transition'
import Portal from './Portal.svelte'
import type { Snippet } from 'svelte'
type Props = {
children: Snippet
}
const { children }: Props = $props()
let isOpen = $state(false)
let mousePos = $state({ x: 0, y: 0 })
@@ -19,7 +26,7 @@
<Portal>
{#if isOpen}
<div
transition:fly={{ x: 0, y: -10, duration: 200 }}
in:fly={{ x: 0, y: -10, duration: 120 }}
use:clickOutside={{
onClickOutside: (e) => {
isOpen = false
@@ -30,6 +37,7 @@
class="absolute left-0 top-0 z-[9999] w-fit"
style="transform: translate({mousePos.x}px, {mousePos.y}px)"
>
{@render children()}
</div>
{/if}
</Portal>
@@ -73,9 +73,8 @@
class:grid-runs-table-no-tag={!containsLabel && !showTag}
class:grid-runs-table-with-labels-no-tag={containsLabel && !showTag}
style="width: {containerWidth}px"
onclick={() => {
dispatch('select')
}}
onclick={() => dispatch('select')}
oncontextmenu={(e) => !selected && dispatch('select')}
>
<!-- Status -->
<div class="flex items-center justify-start pl-4">
@@ -4,13 +4,14 @@
import VirtualList from '@tutorlatin/svelte-tiny-virtual-list'
import { createEventDispatcher } from 'svelte'
import Tooltip from '../Tooltip.svelte'
import { AlertTriangle } from 'lucide-svelte'
import { AlertTriangle, CircleXIcon, RefreshCwIcon } from 'lucide-svelte'
import Popover from '../Popover.svelte'
import { workspaceStore } from '$lib/stores'
import './runs-grid.css'
import { useKeyPressed } from '$lib/svelte5Utils.svelte'
import { twMerge } from 'tailwind-merge'
import RightClickPopover from '../RightClickPopover.svelte'
import DropdownMenu from '../DropdownMenu.svelte'
interface Props {
//import InfiniteLoading from 'svelte-infinite-loading'
@@ -383,7 +384,23 @@
</div>
</div>
<RightClickPopover bind:this={rightClickPopover}></RightClickPopover>
<RightClickPopover bind:this={rightClickPopover}>
<DropdownMenu
closeCallback={() => rightClickPopover?.close()}
items={[
{
label: 'Cancel',
icon: CircleXIcon,
onClick: () => {}
},
{
label: 'Run again',
icon: RefreshCwIcon,
onClick: () => {}
}
]}
/>
</RightClickPopover>
<style>
:global(.virtual-list-wrapper::-webkit-scrollbar) {