Conversation
The message composer is a flex column — editor on top, action row pinned under it — whose height comes only from the `min-height` its host passes (`min-h-24`, or `min-h-30` for the welcome box). The editor claimed its share of that box with `flex-1`: a flex basis of ZERO plus a `min-h-0` floor, so its whole height was free space the container had to hand down. An engine that reads a min-height-only flex column as main-size-indefinite distributes no free space at all, and off a zero basis the editor then lands at 0px. The add / agent / stop controls ride up to the top of the box, the placeholder is clipped away, and everything below the controls is chrome no tap can focus — the mobile-web report in xintaofei#746. Chromium rescues the same markup by resolving the percentage basis as `content`, which is why desktop never showed it. Give the editor a content basis (`grow`) instead. It is then never shorter than the text it holds, whatever the engine does, while `min-h-0` still lets it shrink and scroll once the composer reaches its max height. The blank space under a short draft was also not the contenteditable — only 65% of the editable area was, 40% in the taller welcome box and 24% in the automation editor's prompt box — so focusing it went through the chrome's mousedown fallback, which touch has no reliable equivalent for. Make the scroll area a column and let the editable node grow inside it, so a tap anywhere in the editor lands on it natively. Measured against the built CSS in Chromium at 360px: the composer's box height, editable area and action-row offset are unchanged in every state (empty, image attached, welcome, overflowing) and in all three RichComposer hosts. Only the contenteditable's share of the editable area moves, to 100%. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #746
根因
消息输入框是一个竖向 flex 盒子:编辑区在上、操作按钮行贴在下面。整个盒子的高度只由外层传进来的
min-height决定(普通会话min-h-24,新建会话的欢迎框min-h-30)。问题出在编辑区用
flex-1去拿自己那份高度。flex-1等于「起始高度为 0,再靠父容器分下来的剩余空间长大」,同时还写了min-h-0把下限也放开到 0。也就是说,编辑区的高度全部依赖父容器分配剩余空间。如果浏览器把「只有 min-height、没有确定高度」的竖向 flex 盒子当作主轴尺寸不确定,它就不会分配任何剩余空间。起始高度是 0,编辑区最后就真的是 0px:
这正是 #746 截图里的样子。Chromium 会把百分比起始高度
0%在尺寸不确定时当作content处理,等于替这段写法兜了底,所以桌面端一直看不出问题。顺带修掉第二个问题:短草稿下方那片空白本来就不是 contenteditable 本体——可编辑区域里只有 65% 是它(欢迎框 40%,自动化任务的提示框 24%)。桌面靠外壳上的 mousedown 兜底把焦点塞回编辑器,触摸屏没有对应的可靠事件,于是「点了没反应」。
改动
src/components/chat/composer/rich-composer.tsx、src/components/chat/message-input.tsx:grow)代替零起始高度(flex-1)。这样不管浏览器分不分配剩余空间,编辑区至少和它装的文字一样高,绝不会塌成 0;min-h-0保留,输入框到达最大高度时照样能收缩并滚动。没有动任何绝对定位,也没有改按钮、发送、停止、附件、Agent 选择这些交互。
测试
新增回归测试(jsdom 没有排版引擎,所以锁的是盒模型声明本身,也正是被改坏的那一条):
rich-composer.test.tsx— 可编辑区必须用内容起始高度、不能回退成flex-1;contenteditable 必须能在滚动区里长满。message-input.test.tsx— 编辑区不能用零起始高度;操作按钮行必须是固定高度、且排在编辑区之后。pnpm test全量跑:6621/6625 通过。挂掉的是forge-page.test.tsx和task-settings-dialog.test.tsx里几条 5 秒超时的用例,和本次改动无关——这两个文件都不引用输入框相关代码,单独跑 78/78 全过(其中一条本身就要 4.8 秒),连续两次全量跑挂的用例集合还不一样(4 条 → 1 条),是本机并发下的抖动。真实排版验证
用构建产物的真实 CSS(
pnpm build出来的 chunk)加上组件真实渲染出的 DOM,在 Chromium(headless Edge)360px 宽下逐像素量过,并且用 CSS 模拟了「不分配 min-height 剩余空间」的引擎行为做对照。改动前后,正常引擎下每种状态的盒子高度、可编辑区位置和高度、按钮行偏移完全一致:
三个用到 RichComposer 的地方(会话输入框、自动化编辑器、任务抽屉输入框)几何尺寸都没变。唯一变化的是 contenteditable 在可编辑区里的占比:65% / 40% / 24% → 全部 100%。
模拟故障引擎下:
手工验证范围
请在真机上确认这几点(我没有真机,见下方未验证说明):
未验证部分
visualViewport表现没有测过;本次没有改动这方面的逻辑。🤖 Generated with Claude Code