<script lang="ts" generics="T">
	import type { Snippet } from 'svelte';

	interface Props {
		data: T[];
		children: Snippet<[T]>;
		header: Snippet;
		mobileRow?: Snippet<[T]>;
		empty?: string;
	}
	let { data, children, header, mobileRow, empty = 'No data' }: Props = $props();
</script>

<div class="table-wrap">
	<table class="desktop-table">
		<thead>
			<tr>{@render header()}</tr>
		</thead>
		<tbody>
			{#each data as row (row)}
				<tr>{@render children(row)}</tr>
			{:else}
				<tr><td class="empty" colspan="99">{empty}</td></tr>
			{/each}
		</tbody>
	</table>
	{#if mobileRow}
		<div class="mobile-list">
			{#each data as row (row)}
				{@render mobileRow(row)}
			{:else}
				<div class="empty">{empty}</div>
			{/each}
		</div>
	{/if}
</div>

<style>
	.table-wrap {
		overflow-x: auto;
		width: 100%;
		-webkit-overflow-scrolling: touch;
		scrollbar-gutter: stable both-edges;
	}
	table {
		/* Allow wide tables to scroll horizontally without clipping columns */
		width: max-content;
		min-width: 100%;
		border-collapse: collapse;
	}
	.mobile-list { display: none; flex-direction: column; gap: 1px; }
	:global(th) {
		text-align: left;
		padding: 8px 12px;
		font-size: var(--font-size-xs);
		font-weight: 600;
		color: var(--text-dim);
		text-transform: uppercase;
		letter-spacing: 0.05em;
		border-bottom: 1px solid var(--border);
		white-space: nowrap;
	}
	:global(td) {
		padding: 10px 12px;
		border-bottom: 1px solid var(--border-subtle);
		font-size: var(--font-size-sm);
	}
	:global(tr:hover td) { background: var(--surface-hover); }
	.empty {
		text-align: center;
		color: var(--text-muted);
		padding: 32px 12px;
	}
	@media (max-width: 768px) {
		.desktop-table { display: none; }
		.mobile-list { display: flex; }
	}
</style>
