summaryrefslogtreecommitdiffstatshomepage
path: root/frontend/src/lib/components/Dropdown.svelte
blob: e2979e6b74615b885be67166ef710e9b2ac22e46 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<script lang="ts">
	import { fadeFast } from '$lib/Transitions';
	import type { Snippet } from 'svelte';
	import { fade } from 'svelte/transition';

	interface Props {
		button: Snippet<[() => void]>;
		children?: Snippet;
	}

	let { button, children }: Props = $props();

	let visible = $state(false);

	function onfocusout(event: FocusEvent & { currentTarget: EventTarget & HTMLDivElement }) {
		if (
			event.relatedTarget instanceof HTMLElement &&
			event.currentTarget.contains(event.relatedTarget)
		) {
			return;
		}

		visible = false;
	}
</script>

<div class="relative" {onfocusout}>
	{@render button(() => (visible = !visible))}
	{#if visible}
		<div
			class="absolute z-1 mt-1 w-max rounded-sm bg-slate-700 p-1 shadow-xs shadow-slate-900"
			transition:fade={fadeFast}
		>
			{@render children?.()}
		</div>
	{/if}
</div>