From 7d15ae307047c8ab72c8b126db1672745c3345b1 Mon Sep 17 00:00:00 2001 From: Jure <44338+hoornet@users.noreply.github.com> Date: Mon, 15 Jun 2026 21:30:13 +0200 Subject: [PATCH] feat: collapse compose box to a single line when idle (#6) The posting area was always full-height, which felt oversized (reported on macOS). It now shows a single line when empty and unfocused, and expands to full height + toolbar on focus or when it has content. Uses focus-within blur semantics so clicking the emoji/attach/poll/post controls doesn't collapse it mid-interaction, and resets the auto-resize inline height on collapse. A saved draft starts expanded. Part of #6 --- src/components/feed/ComposeBox.tsx | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/components/feed/ComposeBox.tsx b/src/components/feed/ComposeBox.tsx index f939718..bf561c5 100644 --- a/src/components/feed/ComposeBox.tsx +++ b/src/components/feed/ComposeBox.tsx @@ -25,9 +25,23 @@ export function ComposeBox({ onPublished, onNoteInjected }: { onPublished?: () = const [showEmoji, setShowEmoji] = useState(false); const [isPoll, setIsPoll] = useState(false); const [pollOptions, setPollOptions] = useState(["", ""]); + const [focused, setFocused] = useState(false); const autoResize = useAutoResize(3, 12); const textareaRef = useRef(null); + // Collapse the compose box to a single line when it's idle (empty + not + // focused), expand to full height + toolbar on focus or when there's + // content. Keeps the feed header compact (issue #6). + const expanded = focused || text.trim().length > 0 || attachments.length > 0 || isPoll; + + // When the box collapses, clear the inline height useAutoResize set so the + // rows={1} attribute governs the single-line height again. + useEffect(() => { + if (!expanded && textareaRef.current) { + textareaRef.current.style.height = ""; + } + }, [expanded]); + const { profile, npub } = useUserStore(); const avatar = typeof profile?.picture === "string" ? profile.picture : undefined; const name = profileName(profile, npub ? shortenPubkey(npub) : ""); @@ -244,7 +258,15 @@ export function ComposeBox({ onPublished, onNoteInjected }: { onPublished?: () = {/* Input area */} -
+
setFocused(true)} + onBlur={(e) => { + // Keep expanded while focus moves to a child control (emoji, + // attach, poll, post); only collapse when focus truly leaves. + if (!e.currentTarget.contains(e.relatedTarget as Node)) setFocused(false); + }} + >