<script lang="ts">
	import type { Component, Snippet } from "svelte";
	import type { SvelteHTMLElements } from "svelte/elements";

	interface Props {
		/** plain-text label — omit and render whatever you need through `label` */
		title?: string;
		/** muted explanation under the title; pass an array to get one line each */
		description?: string | string[];
		icon?: Component<SvelteHTMLElements["svg"]>;
		/** replaces `title`/`icon` when the leading side is more than a label */
		label?: Snippet;
		/** trailing controls: buttons, toggles, code chips */
		children?: Snippet;
		/** top-align the control instead of centring it, for tall right-hand content */
		align?: "center" | "start";
		/**
		 * drop the trailing controls onto their own line below sm. Set it wherever the
		 * design does: rows carrying a 320px field, a long identifier, or a labelled
		 * button next to a wide leading block. Short label/toggle pairs stay on one line.
		 */
		stack?: boolean;
		class?: string;
	}

	let {
		title,
		description,
		icon,
		label,
		children,
		align = "center",
		stack = false,
		class: className
	}: Props = $props();

	const alignClass = $derived(
		align === "start"
			? stack
				? "sm:items-start"
				: "items-start"
			: stack
				? "sm:items-center"
				: "items-center"
	);

	const Glyph = $derived(icon);
	const lines = $derived(
		description === undefined ? [] : Array.isArray(description) ? description : [description]
	);
</script>

<div
	class="flex min-h-8 w-full justify-between {stack
		? 'flex-col gap-2 sm:flex-row sm:gap-4'
		: 'gap-4'} {alignClass} {className ?? ''}"
>
	{#if label}
		{@render label()}
	{:else}
		<span class="flex min-w-0 flex-col">
			<span class="flex items-center gap-2">
				{#if Glyph}
					<Glyph class="size-3.5 shrink-0 text-foreground-default" aria-hidden="true" />
				{/if}
				<span class="typography-paragraph-regular text-foreground-default">{title}</span>
			</span>
			{#each lines as line (line)}
				<span class="typography-paragraph-regular text-foreground-muted">{line}</span>
			{/each}
		</span>
	{/if}
	{#if children}
		<!-- stacked, the controls take the full line and align right; a field that wants
		     the whole width says so with `w-full sm:w-80` and fills it instead -->
		<div
			class="flex items-center gap-2 {stack
				? 'w-full justify-end sm:w-auto sm:shrink-0'
				: 'shrink-0'}"
		>
			{@render children()}
		</div>
	{/if}
</div>
