Files
applications-tracker/site/src/lib/InplaceDialog.svelte

47 lines
1002 B
Svelte

<script lang="ts">
import { onDestroy, onMount, type Snippet } from 'svelte';
let {
buttonChildren,
children,
dialogClass = '',
buttonClass = ''
}: {
buttonChildren: Snippet;
children: Snippet;
dialogClass?: string;
buttonClass?: string;
} = $props();
let open = $state(false);
let ref: HTMLDivElement;
let btn: HTMLButtonElement;
function callOutside(e: MouseEvent) {
if (!ref) return;
if (ref.contains(e.target as any) || btn.contains(e.target as any)) return;
open = false;
}
onMount(() => {
window.document.addEventListener('click', callOutside);
});
onDestroy(() => {
window.document.removeEventListener('click', callOutside);
});
</script>
<div class="relative">
<button class={buttonClass} onclick={() => (open = true)} bind:this={btn}>
{@render buttonChildren()}
</button>
{#if open}
<div
bind:this={ref}
class="absolute top-full left-0 bg-white p-2 rounded-lg shadow-lg {dialogClass}"
>
{@render children()}
</div>
{/if}
</div>