<script module lang="ts">
	import { tv, type VariantProps } from "tailwind-variants";

	export const textareaField = tv({
		base: "min-h-20 w-full resize-y rounded border bg-background-default px-3 py-2 text-sm transition-colors placeholder:text-foreground-placeholder focus:outline-none",
		variants: {
			error: {
				false:
					"border-border-default focus:border-border-strong focus:ring-1 focus:ring-border-strong",
				true: "border-border-danger bg-background-danger-subtle text-foreground-danger focus:border-border-focus-danger focus:ring-1 focus:ring-border-focus-danger"
			},
			disabled: {
				false: "",
				true: "cursor-not-allowed resize-none bg-background-inset text-foreground-disabled"
			},
			readonly: {
				false: "",
				true: "cursor-default resize-none bg-background-subtle"
			}
		},
		defaultVariants: {
			error: false,
			disabled: false,
			readonly: false
		}
	});

	export type TextareaFieldVariants = VariantProps<typeof textareaField>;
</script>

<script lang="ts">
	import type { HTMLTextareaAttributes } from "svelte/elements";
	import Spinner from "./Spinner.svelte";

	interface Props extends Omit<HTMLTextareaAttributes, "class" | "value"> {
		value?: string;
		error?: boolean;
		disabled?: boolean;
		loading?: boolean;
		readonly?: boolean;
		class?: string;
	}

	let {
		value = $bindable(""),
		error = false,
		disabled = false,
		loading = false,
		readonly = false,
		class: className,
		...rest
	}: Props = $props();

	const classes = $derived(textareaField({ error, disabled, readonly, class: className }));
</script>

<div class="relative">
	<textarea
		bind:value
		{disabled}
		{readonly}
		aria-invalid={error}
		aria-busy={loading}
		class={classes}
		{...rest}></textarea>
	{#if loading}
		<Spinner class="absolute right-2 top-2 size-4" />
	{/if}
</div>
