From 4204c89f54ff585142424a67b6f863ef677d81c9 Mon Sep 17 00:00:00 2001 From: eti Date: Wed, 29 Jul 2026 23:51:05 +0200 Subject: [PATCH] web/components: give the textarea a floor instead of a ceiling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit max-h-64 capped the field; min-h-64 gives it a comfortable starting height and lets it grow. the text inset also moves from the wrapper onto the textarea, so the scrollbar and the resize handle sit flush against the border rather than floating inside the wrapper's padding — the icon slots and the loading spinner now carry their own inset instead. Signed-off-by: eti --- web/src/lib/components/ui/Textarea.svelte | 25 ++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/web/src/lib/components/ui/Textarea.svelte b/web/src/lib/components/ui/Textarea.svelte index 4022d9d3..26f797cf 100644 --- a/web/src/lib/components/ui/Textarea.svelte +++ b/web/src/lib/components/ui/Textarea.svelte @@ -3,9 +3,9 @@ export const textareaField = tv({ slots: { - root: "relative flex max-h-64 items-start gap-1 rounded border bg-background-default px-2.5 py-2 transition-colors", + root: "relative flex min-h-64 items-start gap-1 rounded border bg-background-default transition-colors", textarea: - "min-h-24 flex-1 bg-transparent text-sm leading-6 outline-none placeholder:text-foreground-placeholder read-only:resize-none disabled:cursor-not-allowed disabled:resize-none" + "min-h-24 flex-1 self-stretch bg-transparent py-2 text-sm leading-6 outline-none placeholder:text-foreground-placeholder read-only:resize-none disabled:cursor-not-allowed disabled:resize-none" }, variants: { error: { @@ -77,12 +77,24 @@ }: Props = $props(); const { root, textarea } = $derived(textareaField({ error, disabled, readonly, resizeable })); + + // The root no longer carries the text inset (so the scrollbar/resize handle can sit flush + // against the border) — the textarea itself owns its horizontal padding, collapsing to 0 on + // whichever side an icon (or the loading spinner) already provides the inset instead. + const textareaPadding = $derived( + [iconLeft ? "" : "pl-2.5", loading ? "pr-[1.875rem]" : iconRight ? "" : "pr-2.5"] + .filter(Boolean) + .join(" ") + );
{#if iconLeft} {@const IconLeft = iconLeft} -
-- 2.51.2