<script lang="ts">
	import { Tabs } from 'bits-ui';
	import type { Snippet } from 'svelte';

	type Tab = { value: string; label: string };

	type Props = {
		tabs: Tab[];
		value?: string;
		/** Rendered once per tab; receives that tab's value. */
		panel: Snippet<[string]>;
		class?: string;
	};

	let {
		tabs,
		value = $bindable(tabs[0]?.value ?? ''),
		panel,
		class: className = ''
	}: Props = $props();
</script>

<Tabs.Root bind:value class="flex min-h-0 flex-col {className}">
	<Tabs.List class="flex gap-1 rounded-md bg-surface-sunken p-1">
		{#each tabs as tab (tab.value)}
			<Tabs.Trigger
				value={tab.value}
				data-testid="tab-{tab.value}"
				class="flex-1 cursor-pointer rounded-md px-3 py-1.5 text-sm font-medium text-ink-muted transition-colors data-[state=active]:bg-surface-raised data-[state=active]:text-ink"
			>
				{tab.label}
			</Tabs.Trigger>
		{/each}
	</Tabs.List>
	{#each tabs as tab (tab.value)}
		<Tabs.Content value={tab.value} class="mt-2 min-h-0 flex-1">
			<!-- Only the open tab is rendered. Bits keeps inactive panels mounted
			     (just hidden), which for a page of independent panels means every
			     one of them fetches its data on arrival and hidden controls sit in
			     the DOM where a click can never reach them. -->
			{#if tab.value === value}{@render panel(tab.value)}{/if}
		</Tabs.Content>
	{/each}
</Tabs.Root>
