99 lines
No EOL
2.1 KiB
Svelte
99 lines
No EOL
2.1 KiB
Svelte
<script lang="ts">
|
|
import { DropdownMenu as DropdownMenuBase } from 'bits-ui'
|
|
import type { Snippet } from 'svelte'
|
|
|
|
interface DropdownMenuProps {
|
|
trigger: Snippet
|
|
menu: Snippet
|
|
open?: boolean
|
|
}
|
|
|
|
let { trigger, menu, open = $bindable(false) }: DropdownMenuProps = $props()
|
|
</script>
|
|
|
|
<DropdownMenuBase.Root bind:open>
|
|
<DropdownMenuBase.Trigger>
|
|
{@render trigger()}
|
|
</DropdownMenuBase.Trigger>
|
|
|
|
<DropdownMenuBase.Portal>
|
|
<DropdownMenuBase.Content class="dropdown-menu" side="bottom" align="start" sideOffset={4}>
|
|
{@render menu()}
|
|
</DropdownMenuBase.Content>
|
|
</DropdownMenuBase.Portal>
|
|
</DropdownMenuBase.Root>
|
|
|
|
<style lang="scss">
|
|
@use '$src/themes/spacing' as *;
|
|
@use '$src/themes/layout' as *;
|
|
@use '$src/themes/typography' as *;
|
|
@use '$src/themes/effects' as *;
|
|
|
|
:global(.dropdown-menu) {
|
|
background: var(--app-bg, white);
|
|
border: 1px solid var(--border-color, #ddd);
|
|
border-radius: $card-corner;
|
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
padding: $unit-half;
|
|
min-width: calc($unit * 22.5);
|
|
z-index: 200;
|
|
animation: slideIn $duration-quick ease-out;
|
|
}
|
|
|
|
:global(.dropdown-menu-item) {
|
|
padding: $unit $unit-2x;
|
|
border-radius: $item-corner-small;
|
|
cursor: pointer;
|
|
font-size: $font-regular;
|
|
color: var(--text-primary);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: $unit;
|
|
@include smooth-transition($duration-standard, background);
|
|
|
|
&:hover {
|
|
background: var(--button-contained-bg-hover, #f5f5f5);
|
|
}
|
|
|
|
&:first-child {
|
|
border-top-left-radius: $item-corner;
|
|
border-top-right-radius: $item-corner;
|
|
}
|
|
|
|
&:last-child {
|
|
border-bottom-left-radius: $item-corner;
|
|
border-bottom-right-radius: $item-corner;
|
|
}
|
|
|
|
&:disabled {
|
|
opacity: 0.5;
|
|
cursor: not-allowed;
|
|
}
|
|
}
|
|
|
|
:global(.dropdown-menu-item.danger) {
|
|
color: var(--danger);
|
|
|
|
&:hover {
|
|
background: var(--danger-bg);
|
|
}
|
|
}
|
|
|
|
:global(.dropdown-menu-separator) {
|
|
border-radius: $full-corner;
|
|
height: 2px;
|
|
background: var(--menu-separator);
|
|
margin: $unit-half ($unit * 0.75);
|
|
}
|
|
|
|
@keyframes slideIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-$unit-fourth);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
</style> |