<script setup lang="ts">
import { onMounted, ref, useId } from 'vue'

const props = defineProps<{
	label?: string
	placeholder?: string
	rows?: number
	error?: string
	autoresize?: boolean
}>()

const model = defineModel<string>()
const id = useId()

const height = ref()

const textareaRef = ref<HTMLTextAreaElement | null>(null)
function resize(target: HTMLTextAreaElement) {
	target.style.height = 'auto'
	target.style.height = `${target.scrollHeight}px`
	height.value = target.scrollHeight
}

function onInput(e: Event) {
	if (!props.autoresize) return
	resize(e.target as HTMLTextAreaElement)
}

onMounted(() => {
	if (props.autoresize && textareaRef.value) {
		resize(textareaRef.value)
	}
})
</script>

<template>
	<div class="input-group">
		<label v-if="label" :for="id" class="label">{{ label }}</label>
		<textarea
			ref="textareaRef"
			:id="id"
			v-model="model"
			v-bind="props"
			rows="1"
			:style="{ height: height + 'px' }"
			:placeholder="placeholder"
			class="input textarea"
			:oninput="onInput"
			:class="{ 'has-error': error }"
		></textarea>
		<span v-if="error" class="error-text">{{ error }}</span>
	</div>
</template>

<style scoped>
.input-group {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	width: 100%;
	margin-bottom: 1rem;
}

.label {
	font-size: 0.875rem;
	font-weight: 600;
	color: hsl(var(--subtext1));
	margin-left: 0.25rem;
}

textarea {
	width: 100%;
	border-radius: 0.75rem;
	border: 1px solid transparent;
	background-color: hsla(var(--surface0) / 0.3);
	border: 1px solid hsla(var(--surface2) / 0.5);
	color: hsl(var(--text));
	font-size: 1rem;
	font-family: inherit;
	resize: none;

	box-sizing: border-box; /* usually default, but good to be sure */
	line-height: 1.5; /* or whatever fits your design system */
	min-height: 0; /* overrides some user-agent defaults */
	overflow: hidden; /* hides the scrollbar jumping */

	&:focus-visible {
		background-color: hsla(var(--base) / 0.9);
	}
	&.has-error {
		border-color: hsl(var(--red));
	}
}
.error-text {
	font-size: 0.75rem;
	color: hsl(var(--red));
	margin-left: 0.25rem;
}
</style>
