Problem
The same input handles “why” and a two-thousand-word brief pasted from a doc. It has to accept files, expose a model choice, a mode toggle and a send button, stay reachable from the keyboard, and take up as little of the screen as possible so the answer above it stays readable.
Solution
Start with a textarea that grows with its content up to a ceiling, then scrolls internally. The ceiling is the part people forget. Unbounded growth means a long prompt pushes the conversation off the top of the screen, so the viewer loses the thing they’re responding to at exactly the moment they’re responding to it. Somewhere around a third of the viewport is a reasonable cap.
Then decide what Enter does, which is the most contested question in the pattern and has no correct answer. Enter-to-send suits short conversational turns and makes the product feel fast. Enter-for-newline suits people who write structured prompts with paragraphs and lists. Both populations use the same product. Most ship Enter-to-send with Shift+Enter for newline, then add a preference once enough people have accidentally fired off half a thought. An accidental send burns a generation and leaves an incomplete question in the permanent transcript for the model to answer.
Paste deserves special handling. Someone dropping four thousand words in to be summarised produces a composer that fills the screen and a user turn that dwarfs every answer. Converting a large paste into an attachment keeps the input compact and makes the content addressable.
The rest is unglamorous and load-bearing:
- Focus returns after send. Losing it means every follow-up costs a click.
- Drafts survive navigation. Clicking a conversation in the sidebar and coming back to an empty box destroys real work, and it is a trivial thing to persist.
- The drop target is the whole conversation area, not the small box. Nobody aims a dragged file at a 40-pixel strip.
- The control row inside the composer is finite. Attach, model, mode, voice, send. Every feature team wants a sixth icon. Hold the line, because the composer is the one surface where a crowded row directly costs input space.
HAX guideline 7 asks for efficient invocation: make the assistant cheap to summon and cheap to use. A composer that’s always present, always focused, and always the same size is the strongest form of that.
Use when
Any interface with repeated free-text turns and a visible history.
Don’t use when
The input is a single-shot query with no follow-up, or the interaction is an inline rewrite on a selection. Both want a field shaped like a search box or a small popover, and neither benefits from an attachment rail and a model switcher.
Trade-offs
Every option surfaced in the composer costs input width and adds a decision before the viewer has typed anything. Auto-growth trades a comfortable writing area against the readable conversation above it, and the two can’t both win. Enter-to-send is fast and destroys unfinished thoughts; Enter-for-newline is safe and makes the product feel sluggish to everyone writing one-liners. A sticky composer pinned to the bottom is the standard answer and eats vertical space on short viewports, where a long answer has least room to begin with.
Checklist
- What’s the maximum height, and what does the conversation look like when the composer is at it?
- What does Enter do, is that discoverable, and can it be changed?
- What happens when someone pastes four thousand words?
- Does focus return to the input after send?
- Does a half-written draft survive navigating away and back?
- Is the whole conversation area a drop target, or only the box?
- How many controls are in the row, and what’s the rule for adding another?
- Does the composer stay usable while a response streams?
- Is the send control reachable and labelled for a screen reader, including in its stop state?
- On a phone, how much of the screen is left for the answer once the keyboard is up?
Compare
ChatGPT keeps the composer live during generation so a follow-up can be drafted while the answer arrives, which treats the box as a workspace rather than a turnstile. Claude turns a large paste into an attachment instead of a wall of text, so the transcript keeps its shape when someone drops in a document. Perplexity biases the whole composer toward a single query with source and focus controls beside it, closer to a search field than a message box. Raycast removes the persistent composer entirely and makes invocation a keystroke into a command bar. That’s HAX guideline 7 taken to its conclusion, and it costs the running history a pinned composer gets for free.
Related
Attachment tray is what appears above the composer once a file is added. Command menu lives inside it and is triggered from it. Stop generation borrows its send slot mid-response. Message turn is what the composer produces. Model picker is the control most often crammed into the same row.