feat(web): auto-grow composer and add expandable editing mode - #1121
Conversation
- Grow the chat textarea with its content up to a 1/4-viewport cap. - Add an expand toggle above the send button for a taller editor; in that mode Enter inserts a newline and Cmd/Ctrl+Enter or the button sends, then the editor collapses back.
🦋 Changeset detectedLatest commit: dfa4310 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8a14cb0b3a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| // inserts a newline instead of sending (send via the button or Cmd/Ctrl+Enter); | ||
| // it auto-collapses after a successful send. See handleKeydown / handleSubmit. | ||
| // --------------------------------------------------------------------------- | ||
| const expanded = ref(false); |
There was a problem hiding this comment.
Reset expanded mode on session changes
Because expanded is a component-level ref and is only reset after submit/steer, changing props.sessionId leaves the previous session's expanded state active while useComposerDraft loads a different draft. If a user expands the composer in one chat and then selects another session or a new empty draft, the new composer opens as a 70vh editor and plain Enter inserts newlines instead of sending, even though the user did not opt into expanded mode for that session. Reset this state when the session id changes, or scope it per session.
Useful? React with 👍 / 👎.
The composer instance is reused across sessions (not keyed by session id), so the expanded preference leaked into the next session's draft, leaving it stuck in the tall editor with Enter inserting newlines. Collapse back when the active session changes.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 36d67ceedd
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| // The expand toggle is hidden at the resting height and only appears once the | ||
| // box has grown past it (multi-line content) — keeps the empty composer | ||
| // uncluttered. While expanded it always shows so the user can collapse back. | ||
| const RESTING_HEIGHT_PX = 56; |
There was a problem hiding this comment.
Use the actual resting height for expand visibility
In the default modern theme (loadTheme falls back to modern, and the global .ph override sets min-height: 40px), this hard-coded 56px threshold makes two-line drafts auto-grow to roughly 50px at the default 14px UI font but still leave isGrown false. The expand button therefore stays hidden until a third line, so the new expanded editor is unavailable for short multiline prompts in the default UI; derive the threshold from computed styles/client height or keep it in sync with the theme CSS.
Useful? React with 👍 / 👎.
The modern/kimi global theme overrides the composer min-height to 40px (the scoped default is 56px), so a hard-coded 56px threshold kept the expand toggle hidden until a third line under the default theme. Read the computed min-height from the element instead.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6e051dd1c0
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const el = textareaRef.value; | ||
| // Registered after useComposerDraft's autosize watcher, so the inline | ||
| // height already reflects the latest content when this reads scrollHeight. | ||
| isGrown.value = !!el && el.scrollHeight > restingHeightPx(el); |
There was a problem hiding this comment.
Recompute growth after collapsing the editor
When the user edits text while the composer is expanded, this check reads the expanded CSS min-height (70vh) instead of the collapsed resting height, so ordinary multi-line drafts shorter than 70vh set isGrown to false. If the user then collapses, v-if="expanded || isGrown" hides the expand button even though the collapsed textarea is still multi-line, leaving no way to re-open the tall editor until another text change occurs.
Useful? React with 👍 / 👎.
While expanded the computed min-height is 70vh, so a multi-line draft measured there sets isGrown=false. Collapsing did not recompute it, hiding the toggle even though the collapsed draft was still multi-line. Recompute growth after every toggle via a shared helper. The expanded state itself is unchanged and stays at 70vh until toggled or sent.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 39eccb0ddf
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| slashOpen.value = false; | ||
| mentionOpen.value = false; | ||
| // A successful send collapses the expanded editor back to its resting size. | ||
| if (expanded.value) expanded.value = false; |
There was a problem hiding this comment.
Collapse expanded editor before slash-command returns
In handleSubmit, known slash commands return above this newly added collapse. When a user expands to compose a long /goal ..., /btw ..., /compact ..., or skill command and sends with Cmd/Ctrl+Enter or the send button, the command is emitted and text is cleared, but expanded stays true, leaving an empty 70vh editor until the user manually collapses it. Move the collapse/reset into the slash-command path or a shared success cleanup as well.
Useful? React with 👍 / 👎.
Known slash commands return early from handleSubmit, above the post-send collapse, so sending an expanded /goal, /btw, /compact, or skill command left an empty 70vh editor. Collapse in the slash-command path too.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9843c4c9d0
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| void nextTick(() => { | ||
| autosize(); | ||
| recomputeGrown(); | ||
| }); |
There was a problem hiding this comment.
Refocus the textarea after toggling expand
When the user activates the new expand button while composing, browser focus remains on that button because this callback only resizes/recomputes the textarea. In that state the next keystrokes do not enter the expanded editor, and pressing Enter can activate the button again instead of inserting a newline, so the user must click back into the textarea before continuing the long message.
Useful? React with 👍 / 👎.
Clicking the expand toggle leaves focus on the button, so subsequent keystrokes do not reach the textarea and Enter would activate the button again instead of inserting a newline. Return focus to the textarea after toggling.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 826bf3e871
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| @@ -232,6 +298,8 @@ function handleSubmit(): void { | |||
| text.value = ''; | |||
| slashOpen.value = false; | |||
There was a problem hiding this comment.
Refit the textarea when collapsing after image-only sends
If the editor is expanded, the user deletes all text and sends an attachment-only message, text.value is already empty, so the draft composable's text watcher never runs autosize() after expanded flips false. The textarea can keep the inline height measured while the 70vh min-height was active; the collapsed CSS only caps it at 100vh / 4, leaving an empty oversized composer until the next input. Re-run autosize when collapsing on submit paths that do not change the text.
Useful? React with 👍 / 👎.
When the expanded editor collapses on an image-only send, the text is already empty so the draft watcher never re-runs autosize; the textarea kept the inline height measured at 70vh and the collapsed cap left an oversized empty box. Route all send/steer collapses through a helper that re-runs autosize after the 70vh min-height is removed.
|
Codex Review: Didn't find any major issues. Swish! Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
Related Issue
N/A — no prior issue; the limitation is described below.
Problem
The web chat composer was pinned to a fixed 56px height, so anything past a single line scrolled inside a tiny box. There was also no comfortable way to write a longer multi-line message:
Enteralways sent, so adding newlines meant holdingShiftevery time.What changed
Enterinserts a newline andCmd/Ctrl+Enter(or the send button) sends; the editor collapses back after sending. The toggle stays hidden while the input is at its resting height so the empty composer stays uncluttered.The existing single-line
Enter-to-send flow is unchanged. Added unit coverage for the auto-grow sizing; the expand toggle is a thin UI affordance covered by typecheck (the web app has no component-test harness).Checklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.