<script module lang="ts">
import { tv, type VariantProps } from "tailwind-variants";
export const dropdownItem = tv({
base: "w-full justify-start rounded-[calc(var(--radius-md)-var(--spacing))] px-xs text-left focus-visible:-outline-offset-2",
variants: {
danger: {
false: "",
true: "text-foreground-danger hover:bg-background-danger-subtle"
}
},
defaultVariants: {
danger: false
}
});
export type DropdownItemVariants = VariantProps<typeof dropdownItem>;
</script>
<script lang="ts">
import type { ResolvedPathname } from "$app/types";
import type { Component, Snippet } from "svelte";
import type { SvelteHTMLElements } from "svelte/elements";
import { getContext } from "svelte";
import Button, { type ButtonVariants } from "#lib/components/ui/Button.svelte";
interface Props {
href?: ResolvedPathname;
target?: string;
rel?: string;
download?: string;
title?: string;
icon?: Component<SvelteHTMLElements["svg"]>;
danger?: DropdownItemVariants["danger"];
disabled?: boolean;
onclick?: (event: MouseEvent) => void;
/** Button hugs its children, so a two-column row needs `[&>span]:w-full` here. */
class?: string;
children: Snippet;
size?: ButtonVariants["size"];
"aria-label"?: string;
[attr: `data-${string}`]: unknown;
}
let {
href,
icon,
danger = false,
disabled = false,
onclick,
class: className,
children,
size,
...rest
}: Props = $props();
const classes = $derived(dropdownItem({ danger, class: className }));
const closeDropdown = getContext<(() => void) | undefined>("dropdown-close");
const registerItem = getContext<((el: HTMLElement) => () => void) | undefined>(
"dropdown-register"
);
let el = $state<HTMLAnchorElement | HTMLButtonElement>();
$effect(() => {
if (!el || !registerItem) return;
return registerItem(el);
});
const handleClick = (event: MouseEvent) => {
closeDropdown?.();
onclick?.(event);
};
</script>
<Button
{...rest}
bind:ref={el}
variant="ghost"
{href}
class={classes}
{icon}
role={registerItem ? "menuitem" : undefined}
{disabled}
tabindex={registerItem ? -1 : undefined}
onclick={handleClick}
{size}
>
{@render children()}
</Button>