From c261b8e75b29e7eb33df4028aaceb322c6e15e70 Mon Sep 17 00:00:00 2001 From: mAi Date: Wed, 6 May 2026 16:33:42 +0200 Subject: [PATCH] ui: chat compose grows with content + better default size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - rows='1' → rows='3' so the compose box has presence even when empty (it was a one-line slit, easy to miss). - Add `field-sizing: content` on .fb-compose__textarea so modern browsers (Chrome 123+ / Firefox 137+ / Safari 17.4+) auto-grow it to fit content natively. Cap at the existing max-height: 10rem with overflow-y: auto so long messages don't eat the bubbles scroll area. - For older browsers: feature-detect via CSS.supports('field-sizing', 'content'). When unsupported, an oninput handler sets style.height = scrollHeight + 'px' (capped at 160px). Modern browsers no-op the JS resizer to avoid fighting the native CSS rule. - After send (chatBody → ''), an $effect clears the inline height so the textarea snaps back to rows='3'. Native field-sizing handles this on its own; the effect only fires on the JS-fallback path. - Shorten placeholder to "Nachricht…" — the keyboard hint was chrome the user discovers on their own. --- src/lib/styles/feedback.css | 5 +++++ src/routes/f/[slug]/+page.svelte | 29 +++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/lib/styles/feedback.css b/src/lib/styles/feedback.css index a429e74..5eeb616 100644 --- a/src/lib/styles/feedback.css +++ b/src/lib/styles/feedback.css @@ -1835,6 +1835,11 @@ body { min-height: 100vh; } min-height: 2.5rem; max-height: 10rem; resize: none; + overflow-y: auto; + /* Modern browsers (Chrome 123+ / Firefox 137+ / Safari 17.4+) auto-grow + the textarea to fit its content. Older browsers fall back to the JS + resizer in /f/[slug]/+page.svelte's autosizeCompose. */ + field-sizing: content; } .fb-compose__send { diff --git a/src/routes/f/[slug]/+page.svelte b/src/routes/f/[slug]/+page.svelte index 6592d91..0c872e8 100644 --- a/src/routes/f/[slug]/+page.svelte +++ b/src/routes/f/[slug]/+page.svelte @@ -56,6 +56,7 @@ let pollHandle: ReturnType | null = null; let lastSeenAt: string | null = null; let chatListEl = $state(null); + let composeEl = $state(null); let results = $state(null); let resultsPollHandle: ReturnType | null = null; @@ -436,6 +437,28 @@ } } + // Auto-grow the compose textarea with content. Modern browsers handle this + // natively via `field-sizing: content`; for older browsers we fall back to + // resizing on input. Capped at 10rem (160px) — matches .fb-compose__textarea. + const supportsFieldSizing = + typeof CSS !== 'undefined' && typeof CSS.supports === 'function' + ? CSS.supports('field-sizing', 'content') + : false; + + function autosizeCompose(el: HTMLTextAreaElement): void { + if (supportsFieldSizing) return; + el.style.height = 'auto'; + el.style.height = `${Math.min(el.scrollHeight, 160)}px`; + } + + // Reset the inline height after a send (chatBody → '') so the textarea + // snaps back to its rows="3" default. No-op when field-sizing handles it. + $effect(() => { + if (chatBody === '' && composeEl && !supportsFieldSizing) { + composeEl.style.height = ''; + } + }); + function onComposeKeydown(e: KeyboardEvent): void { // Enter alone (no shift, no IME composition) sends. Shift+Enter inserts a newline. // Cmd/Ctrl+Enter also sends — covers users who expect that shortcut. @@ -800,11 +823,13 @@ >