From f80a8f2ab7a2ec45a81724dadd760eb4e32b4579 Mon Sep 17 00:00:00 2001 From: jollyxenon <1378319314@qq.com> Date: Wed, 13 May 2026 17:54:19 +0800 Subject: [PATCH 01/11] feat(ui): add resizable session composer 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. --- packages/ui/src/components/expand-button.tsx | 37 +- .../components/instance/instance-shell2.tsx | 3 +- packages/ui/src/components/prompt-input.tsx | 916 +++++++++++------- .../ui/src/components/prompt-input/types.ts | 3 - .../src/components/session/session-view.tsx | 1 - .../ui/src/lib/i18n/messages/en/messaging.ts | 2 + .../ui/src/lib/i18n/messages/es/messaging.ts | 2 + .../ui/src/lib/i18n/messages/fr/messaging.ts | 2 + .../ui/src/lib/i18n/messages/he/messaging.ts | 2 + .../ui/src/lib/i18n/messages/ja/messaging.ts | 2 + .../ui/src/lib/i18n/messages/ru/messaging.ts | 2 + .../lib/i18n/messages/zh-Hans/messaging.ts | 2 + .../ui/src/styles/messaging/prompt-input.css | 182 ++-- 13 files changed, 735 insertions(+), 421 deletions(-) diff --git a/packages/ui/src/components/expand-button.tsx b/packages/ui/src/components/expand-button.tsx index 953b3f874..667921aab 100644 --- a/packages/ui/src/components/expand-button.tsx +++ b/packages/ui/src/components/expand-button.tsx @@ -3,16 +3,43 @@ import { Maximize2, Minimize2 } from "lucide-solid" import { useI18n } from "../lib/i18n" interface ExpandButtonProps { - expandState: () => "normal" | "expanded" - onToggleExpand: (nextState: "normal" | "expanded") => void + /** + * Current height of the input container in pixels. + * Used to determine which icon to show (expand vs shrink). + */ + currentHeight: () => number + /** + * Default/minimum height of the input container in pixels. + * When currentHeight exceeds this, the shrink icon is shown. + */ + defaultHeight: () => number + /** + * Callback when the button is clicked. + * true = expand to default expanded height, false = shrink to default height + */ + onToggleExpand: (expand: boolean) => void } +/** + * Expand/shrink button for the prompt input. + * Shows expand icon when at default height, shrink icon when enlarged. + * Clicking toggles between default and expanded heights. + */ export default function ExpandButton(props: ExpandButtonProps) { const { t } = useI18n() + /** + * Determines if the input is currently expanded based on actual height. + * Returns true when current height exceeds the default height. + */ + const isExpanded = () => props.currentHeight() > props.defaultHeight() + + /** + * Handles button click by toggling between expanded and collapsed states. + * Passes true to expand, false to shrink. + */ function handleClick() { - const current = props.expandState() - props.onToggleExpand(current === "normal" ? "expanded" : "normal") + props.onToggleExpand(!isExpanded()) } return ( @@ -23,7 +50,7 @@ export default function ExpandButton(props: ExpandButtonProps) { aria-label={t("expandButton.toggleAriaLabel")} >