Skip to content

feat(ui): add resizable session composer#1

Open
jollyxenon wants to merge 12 commits into
devfrom
feature/session-input-resize
Open

feat(ui): add resizable session composer#1
jollyxenon wants to merge 12 commits into
devfrom
feature/session-input-resize

Conversation

@jollyxenon
Copy link
Copy Markdown
Owner

Summary

  • add a top-edge drag handle for the CodeNomad session composer so the input can be freely resized without shrinking below its default height
  • clamp composer expansion to the visible chat area, keep the right-side controls in a stable three-column layout, and switch the inline control icon between expand and shrink based on the current height
  • reset the composer back to its default height after sending and remove stale prompt-sizing remnants that no longer participate in the new behavior

What Changed

  • replaced the old two-state prompt expansion behavior with a height-driven resize flow in packages/ui/src/components/prompt-input.tsx
  • updated packages/ui/src/components/expand-button.tsx so the control reflects the actual composer height instead of a removed expand state enum
  • revised packages/ui/src/styles/messaging/prompt-input.css to support top-edge dragging, maintain the input / utility controls / primary actions three-column layout, and preserve narrow-window behavior without pushing controls under the textarea
  • added a stable toolbar selector in packages/ui/src/components/instance/instance-shell2.tsx so the composer can clamp against the correct upper boundary
  • added resize-handle localization strings across the existing messaging locale files
  • removed dead prompt-resize remnants (ExpandState, unused compactLayout plumbing, duplicate history draft clearing, unused focus-only signal) that would otherwise leave the feature code internally inconsistent

Why

The previous composer behavior only supported a coarse collapsed/expanded switch and regressed when the new resize affordance was introduced. This change makes height adjustment continuous, keeps the controls anchored where users expect them, and ensures each new send starts from a predictable default composer height.

Validation

  • npm run typecheck --workspace @codenomad/ui
  • npm run build --workspace @codenomad/ui
    • build still emits the pre-existing virtua JSX warning from ../../node_modules/virtua/lib/solid/index.jsx

Notes

  • this PR intentionally excludes unrelated local changes in .opencode/package-lock.json, packages/electron-app/electron.vite.config.ts, packages/electron-app/electron/main/process-manager.ts, and .sisyphus/

Allow the CodeNomad session composer to be resized by dragging its top edge while keeping the minimum height at the default collapsed size and clamping the maximum height to the chat area's visible bounds.

The prompt controls now keep their intended three-column layout during resize, the expand/collapse icon reflects the current height, and sending a message resets the composer back to its default size so follow-up prompts start from a consistent state.

This commit also removes prompt-resize remnants that no longer participate in the new height-based behavior, keeping the implementation aligned with the shipped interaction model.
Copilot AI review requested due to automatic review settings May 13, 2026 09:56
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR replaces the session composer’s previous two-state expand behavior with a height-driven resizing model, adding a top-edge drag handle, clamping growth to the visible chat area, and ensuring the composer resets back to its default height after sending.

Changes:

  • Implement continuous composer resizing via a top-edge drag handle + height signal, and reset height on send.
  • Update the expand/shrink button to reflect the actual current height rather than a removed expand-state enum.
  • Adjust prompt-input layout/CSS to keep controls in a stable three-column grid and add i18n strings for the resize handle.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/ui/src/components/prompt-input.tsx Introduces height-driven resizing logic, drag handle, height reset on send, and updates control layout wiring.
packages/ui/src/components/expand-button.tsx Switches expand/shrink icon logic to be based on current height vs default height.
packages/ui/src/styles/messaging/prompt-input.css Adds resize-handle styling and revises grid layout to keep controls aligned.
packages/ui/src/components/instance/instance-shell2.tsx Adds a stable toolbar selector (data-session-toolbar) for clamping calculations; removes compactLayout prop usage.
packages/ui/src/components/session/session-view.tsx Removes the dropped compactLayout prop when rendering PromptInput.
packages/ui/src/components/prompt-input/types.ts Removes ExpandState and compactLayout from public prompt-input types.
packages/ui/src/lib/i18n/messages/en/messaging.ts Adds localized strings for resize-handle label/title.
packages/ui/src/lib/i18n/messages/es/messaging.ts Adds localized strings for resize-handle label/title.
packages/ui/src/lib/i18n/messages/fr/messaging.ts Adds localized strings for resize-handle label/title.
packages/ui/src/lib/i18n/messages/he/messaging.ts Adds localized strings for resize-handle label/title.
packages/ui/src/lib/i18n/messages/ja/messaging.ts Adds localized strings for resize-handle label/title.
packages/ui/src/lib/i18n/messages/ru/messaging.ts Adds localized strings for resize-handle label/title.
packages/ui/src/lib/i18n/messages/zh-Hans/messaging.ts Adds localized strings for resize-handle label/title.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +372 to +375
// Fallback: use viewport-based calculation
const viewportHeight = window.innerHeight;
const maxFromViewport = viewportHeight - 100;
return Math.max(DEFAULT_EXPANDED_HEIGHT, maxFromViewport);
Comment on lines +808 to +809
aria-label={t("promptInput.resizeHandle.ariaLabel")}
title={t("promptInput.resizeHandle.title")}
Comment on lines +433 to +436
document.addEventListener("pointermove", handlePointerMove);
document.addEventListener("pointerup", handlePointerUp);
document.addEventListener("pointercancel", handlePointerUp);
}
Comment on lines +1 to +20
import {
Suspense,
createEffect,
createSignal,
lazy,
on,
onCleanup,
Show,
} from "solid-js";
import {
ArrowBigUp,
ArrowBigDown,
Loader2,
Mic,
Paperclip,
Volume2,
X,
} from "lucide-solid";
import ExpandButton from "./expand-button";
import { clearAttachments, removeAttachment } from "../stores/attachments";
jollyxenon and others added 11 commits May 13, 2026 20:24
Refine the resizable session composer in response to PR review feedback. Keep the resize cleanup and viewport-based max-height fallback fixes, while removing the newly introduced keyboard resizing behavior so the feature stays aligned with the existing interaction model.

This update prevents document-level pointer listeners from leaking when the composer unmounts mid-drag and avoids over-expanding the composer on small viewports or layouts without the toolbar anchor. It intentionally leaves unrelated local edits in package-lock, Electron dev-server files, and workspace metadata out of the commit.

Validation: npm run typecheck --workspace @codenomad/ui; npm run build --workspace @codenomad/ui
Restore the maintainer-owned prompt model for default height, expand state, and compact narrow-pane behavior while keeping top-edge drag resizing as an additive capability. This keeps the feature aligned with the existing composer interaction model instead of replacing it with a separate height-only workflow.

The commit limits itself to prompt logic and supporting component APIs so the baseline UX remains recognizable. Validation was completed with npm run typecheck --workspace @codenomad/ui and npm run build --workspace @codenomad/ui.
Add the top-edge resize affordance while preserving the maintainer's narrow-pane grid, inline controls, and compact-height rules. The CSS remains responsible for the original responsive layout, and the drag handle only overlays new pointer behavior on top of it.

Validation was completed with npm run typecheck --workspace @codenomad/ui and npm run build --workspace @codenomad/ui.
Add the new resize-handle tooltip text for the locales touched by this branch so the drag affordance remains localized alongside the prompt composer updates. This keeps the new interaction discoverable without changing the maintainer's existing layout semantics.

Validation was completed with npm run typecheck --workspace @codenomad/ui and npm run build --workspace @codenomad/ui.
Limit manual prompt resizing to sixty percent of the local session center so the composer cannot consume the full message area.

The resize handle now lives inside the prompt field container, keeping the affordance visually centered over the text editor instead of spanning the full composer chrome. Removing the toolbar lookup also drops the temporary data attribute from the session toolbar and avoids cross-pane DOM coupling.

Validation: npm run typecheck --workspace @codenomad/ui; npm run build --workspace @codenomad/ui.
Use pointer capture on the resize handle instead of document-level pointer listeners so resize state stays local to the prompt control and no manual listener teardown is needed.

Keep explicit resized-height styling through the prompt field stack because the existing expanded-state CSS otherwise prevents the textarea from filling the resized container. Also remove the whitespace-only prompt input type diff.

Validation: npm run typecheck --workspace @codenomad/ui.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants