This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / web / src / lib / components / ui / DropdownItem.svelte
1.7 kB 67 lines
1<script module lang="ts"> 2 import { tv, type VariantProps } from "tailwind-variants"; 3 4 export const dropdownItem = tv({ 5 base: "w-full justify-start rounded-none p-2 text-left focus-visible:-outline-offset-2", 6 variants: { 7 danger: { 8 false: "", 9 true: "text-foreground-danger hover:bg-background-danger-subtle" 10 } 11 }, 12 defaultVariants: { 13 danger: false 14 } 15 }); 16 17 export type DropdownItemVariants = VariantProps<typeof dropdownItem>; 18</script> 19 20<script lang="ts"> 21 import { resolve } from "$app/paths"; 22 import type { Component, Snippet } from "svelte"; 23 import type { SvelteHTMLElements } from "svelte/elements"; 24 import { getContext } from "svelte"; 25 import Button from "./Button.svelte"; 26 27 interface Props { 28 href?: string; 29 icon?: Component<SvelteHTMLElements["svg"]>; 30 danger?: DropdownItemVariants["danger"]; 31 onclick?: (event: MouseEvent) => void; 32 children: Snippet; 33 } 34 35 let { href, icon, danger = false, onclick, children }: Props = $props(); 36 const classes = $derived(dropdownItem({ danger })); 37 38 const closeDropdown = getContext<(() => void) | undefined>("dropdown-close"); 39 const registerItem = getContext<((el: HTMLElement) => () => void) | undefined>( 40 "dropdown-register" 41 ); 42 43 let el = $state<HTMLAnchorElement | HTMLButtonElement>(); 44 45 $effect(() => { 46 if (!el || !registerItem) return; 47 return registerItem(el); 48 }); 49 50 const handleClick = (event: MouseEvent) => { 51 closeDropdown?.(); 52 onclick?.(event); 53 }; 54</script> 55 56<Button 57 bind:ref={el} 58 variant="ghost" 59 href={href ? resolve(href as "/") : undefined} 60 class={classes} 61 {icon} 62 role="menuitem" 63 tabindex={-1} 64 onclick={handleClick} 65> 66 {@render children()} 67</Button>