* feat(frontend): wip * wip * wip * wip * wip * add toggle * correctly handle monaco theme * wip * wip * wip * wip * wip * feat(frontend): Dark mode v0 * feat(frontend): Adap AI gen poppup * feat(frontend): Adap script metadata labels * feat(frontend): Fix unreadable texts * feat(frontend): Fix unreadable texts * feat(frontend): Fix unreadable texts * feat(frontend): Fix ressource picker * feat(frontend): Fix unreadable texts * feat(frontend): Fix unreadable texts * feat(frontend): Fix unreadable texts * feat(frontend): Add theme toggle in the login page * feat(frontend): Fix unreadable texts * feat(frontend): Fix language selection * feat(frontend): Fix FlowStatusViewer colors * feat(frontend): Fix divide colors * feat(frontend): Fix flow graph buttons * feat(frontend): add theme toggle in login modal * feat(frontend): small ui fix * feat(frontend): fix graph dark mode toggle
120 lines
3.2 KiB
Svelte
120 lines
3.2 KiB
Svelte
<script lang="ts">
|
|
import type { DropdownItem } from '$lib/utils'
|
|
import { createEventDispatcher } from 'svelte'
|
|
import Icon from 'svelte-awesome'
|
|
import { MoreVertical } from 'lucide-svelte'
|
|
import { Button, Menu } from './common'
|
|
import { twMerge } from 'tailwind-merge'
|
|
|
|
type Alignment = 'start' | 'end'
|
|
type Side = 'top' | 'bottom'
|
|
type Placement = `${Side}-${Alignment}`
|
|
|
|
export let dropdownItems: DropdownItem[] | (() => DropdownItem[]) = []
|
|
export let name: string | undefined = undefined
|
|
export let placement: Placement = 'bottom-start'
|
|
export let btnClasses = ''
|
|
$: buttonClass = twMerge('!border-0 bg-transparent !p-[6px]', btnClasses)
|
|
|
|
const dispatch = createEventDispatcher()
|
|
|
|
function computeDropdowns(): DropdownItem[] {
|
|
if (typeof dropdownItems === 'function') {
|
|
return dropdownItems()
|
|
} else {
|
|
return dropdownItems
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<Menu {placement} let:close>
|
|
<Button
|
|
nonCaptureEvent
|
|
color="light"
|
|
variant="border"
|
|
size="xs"
|
|
btnClasses={buttonClass}
|
|
{...$$restProps}
|
|
slot="trigger"
|
|
>
|
|
{#if !$$slots.default}
|
|
<MoreVertical size={16} />
|
|
{:else}
|
|
<slot />
|
|
{/if}
|
|
</Button>
|
|
{#if dropdownItems}
|
|
{#each computeDropdowns() as item, i}
|
|
{#if item.action}
|
|
<button
|
|
on:click|preventDefault|stopPropagation={(event) => {
|
|
if (!item.disabled) {
|
|
close()
|
|
item.action && item.action(event)
|
|
dispatch('click', { item: item?.eventName })
|
|
}
|
|
}}
|
|
class="block w-full whitespace-nowrap hover:drop-shadow-sm hover:bg-surface-hover hover:bg-opacity-30
|
|
px-4 py-2 text-sm text-primary text-left
|
|
{item.disabled ? 'bg-surface-disabled' : ''}
|
|
{item.separatorTop ? 'border-t' : ''} {item.separatorBottom ? 'border-b' : ''} {item.type ==
|
|
'delete'
|
|
? 'text-red-500'
|
|
: ''}"
|
|
role="menuitem"
|
|
tabindex="-1"
|
|
id="user-menu-item-{name}-{i}}"
|
|
disabled={item.disabled}
|
|
>
|
|
{#if item.icon}
|
|
<Icon
|
|
data={item.icon}
|
|
scale={0.6}
|
|
class="inline mr-2 {item.type == 'delete' ? 'text-red-500' : 'text-primary'}"
|
|
/>
|
|
{/if}
|
|
{item.displayName}
|
|
</button>
|
|
{:else if item.href && !item.disabled}
|
|
<a
|
|
href={item.href}
|
|
class="block w-full px-4 font-semibold text-left py-2 text-sm text-secondary hover:drop-shadow-sm hover:bg-gray-50 hover:bg-opacity-30
|
|
{item.disabled ? 'bg-gray-200' : ''}"
|
|
role="menuitem"
|
|
tabindex="-1"
|
|
id="user-menu-item-{name}-{i}}"
|
|
class:disabled={item.disabled}
|
|
>
|
|
{#if item.icon}
|
|
<Icon
|
|
data={item.icon}
|
|
scale={0.6}
|
|
class="inline mr-2 {item.type == 'delete' ? 'text-red-500' : 'text-secondary'}"
|
|
/>
|
|
{/if}
|
|
{item.displayName}
|
|
</a>
|
|
{:else}
|
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
<span
|
|
class:bg-gray-200={item.disabled}
|
|
class="block font-semibold text-left px-4 py-2 text-sm text-secondary cursor-auto"
|
|
role="menuitem"
|
|
tabindex="-1"
|
|
id="user-menu-item-{name}-{i}}"
|
|
on:click|preventDefault|stopPropagation
|
|
>
|
|
{#if item.icon}
|
|
<Icon
|
|
data={item.icon}
|
|
scale={0.6}
|
|
class="inline mr-2 {item.type == 'delete' ? 'text-red-500' : 'text-secondary'}"
|
|
/>
|
|
{/if}
|
|
{item.displayName}
|
|
</span>
|
|
{/if}
|
|
{/each}
|
|
{/if}
|
|
</Menu>
|