This repository has no description
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>