Repository navigation
Keep the chat composer to one focus indicator on web - #89
Merged
Merged
Conversation
The composer pill already signals focus by tinting its border, so Chrome's focus ring on the textarea drew a second, square box inside the rounded pill. Chrome paints outline-style auto at any width, so the fix sets outline-style none on web only.
guidovizoso
approved these changes
Sep 29, 2026
sunshaoan0808
pushed a commit
to sunshaoan0808/openmuse
that referenced
this pull request
Sep 30, 2026
Drop the browser focus ring inside the chat composer The composer pill already signals focus by tinting its border, so Chrome's focus ring on the textarea drew a second, square box inside the rounded pill. Chrome paints outline-style auto at any width, so the fix sets outline-style none on web only.
sunshaoan0808
pushed a commit
to sunshaoan0808/openmuse
that referenced
this pull request
Sep 30, 2026
上游 5 个提交:JEV(CopilotKit#42)、无 scheme worker 地址(CopilotKit#92)、web 输入框焦点(CopilotKit#89)、 worker 测试健壮性(CopilotKit#90)、render 蓝图(CopilotKit#86)。 冲突解决(4 文件 9 块)与本地适配: - conversation.ts:以上游 JEV 结构(runInternal/choices 分支/noteEvidence)为基座, 换回我们的中性工具层(forAgUi + chatTools),并把 noteEvidence 改成经 ChatToolContext 回调; prompt 用我们的 chatInstructions() + JEV 段 + computerInstructions;恢复 maxSteps=10 与 sample 分支的 threadId 注入 - agent.ts:保留我们的 mastra 引擎分支,两处 ConversationAgent 注入 sharedJevAdapter() - chat.tsx:我们的卡片(搜索/浏览器操作/审批)与 JEV 卡片并存,去重 delegate_task 渲染器 - config.ts:去掉 cherry-pick 造成的 browserWorkerUrl 重复定义 - mastra-engine.ts:JEV 工具与指令补到 mastra 路径(上游只挂自带引擎,我们线上跑 mastra) - jev/tools.ts:抽出 presentChoicesSpec 中性规格,两条引擎共用同一份校验逻辑 验证:pnpm test 321/321 通过(含上游 JEV 全部测试)
sunshaoan0808
pushed a commit
to sunshaoan0808/openmuse
that referenced
this pull request
Oct 14, 2026
Drop the browser focus ring inside the chat composer The composer pill already signals focus by tinting its border, so Chrome's focus ring on the textarea drew a second, square box inside the rounded pill. Chrome paints outline-style auto at any width, so the fix sets outline-style none on web only.
sunshaoan0808
pushed a commit
to sunshaoan0808/openmuse
that referenced
this pull request
Oct 14, 2026
Drop the browser focus ring inside the chat composer The composer pill already signals focus by tinting its border, so Chrome's focus ring on the textarea drew a second, square box inside the rounded pill. Chrome paints outline-style auto at any width, so the fix sets outline-style none on web only.
sunshaoan0808
pushed a commit
to sunshaoan0808/openmuse
that referenced
this pull request
Oct 14, 2026
上游 5 个提交:JEV(CopilotKit#42)、无 scheme worker 地址(CopilotKit#92)、web 输入框焦点(CopilotKit#89)、 worker 测试健壮性(CopilotKit#90)、render 蓝图(CopilotKit#86)。 冲突解决(4 文件 9 块)与本地适配: - conversation.ts:以上游 JEV 结构(runInternal/choices 分支/noteEvidence)为基座, 换回我们的中性工具层(forAgUi + chatTools),并把 noteEvidence 改成经 ChatToolContext 回调; prompt 用我们的 chatInstructions() + JEV 段 + computerInstructions;恢复 maxSteps=10 与 sample 分支的 threadId 注入 - agent.ts:保留我们的 mastra 引擎分支,两处 ConversationAgent 注入 sharedJevAdapter() - chat.tsx:我们的卡片(搜索/浏览器操作/审批)与 JEV 卡片并存,去重 delegate_task 渲染器 - config.ts:去掉 cherry-pick 造成的 browserWorkerUrl 重复定义 - mastra-engine.ts:JEV 工具与指令补到 mastra 路径(上游只挂自带引擎,我们线上跑 mastra) - jev/tools.ts:抽出 presentChoicesSpec 中性规格,两条引擎共用同一份校验逻辑 验证:pnpm test 321/321 通过(含上游 JEV 全部测试)
sunshaoan0808
pushed a commit
to sunshaoan0808/openmuse
that referenced
this pull request
Oct 14, 2026
Drop the browser focus ring inside the chat composer The composer pill already signals focus by tinting its border, so Chrome's focus ring on the textarea drew a second, square box inside the rounded pill. Chrome paints outline-style auto at any width, so the fix sets outline-style none on web only.
sunshaoan0808
pushed a commit
to sunshaoan0808/openmuse
that referenced
this pull request
Oct 14, 2026
上游 5 个提交:JEV(CopilotKit#42)、无 scheme worker 地址(CopilotKit#92)、web 输入框焦点(CopilotKit#89)、 worker 测试健壮性(CopilotKit#90)、render 蓝图(CopilotKit#86)。 冲突解决(4 文件 9 块)与本地适配: - conversation.ts:以上游 JEV 结构(runInternal/choices 分支/noteEvidence)为基座, 换回我们的中性工具层(forAgUi + chatTools),并把 noteEvidence 改成经 ChatToolContext 回调; prompt 用我们的 chatInstructions() + JEV 段 + computerInstructions;恢复 maxSteps=10 与 sample 分支的 threadId 注入 - agent.ts:保留我们的 mastra 引擎分支,两处 ConversationAgent 注入 sharedJevAdapter() - chat.tsx:我们的卡片(搜索/浏览器操作/审批)与 JEV 卡片并存,去重 delegate_task 渲染器 - config.ts:去掉 cherry-pick 造成的 browserWorkerUrl 重复定义 - mastra-engine.ts:JEV 工具与指令补到 mastra 路径(上游只挂自带引擎,我们线上跑 mastra) - jev/tools.ts:抽出 presentChoicesSpec 中性规格,两条引擎共用同一份校验逻辑 验证:pnpm test 321/321 通过(含上游 JEV 全部测试)
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.
The problem
When you click into the chat composer on web and start typing, Chrome draws its default focus ring around the textarea. The ring is a dark blue rectangle with square corners, sitting inside a composer that is rounded and already shows focus by tinting its own border light blue. So you see two focus indicators at once, and the square one clashes with the pill every time you type a message.
The approach
The composer keeps its own focus cue (the
focusedstate that tints the pill's border and deepens its shadow), and the textarea inside it stops drawing the browser's ring. This is only for web; nothing changes on iOS or Android.The obvious fix,
outlineWidth: 0, does not work. Chrome paints the:focus-visiblering asoutline-style: auto, which ignores the outline width, so the ring stays. The recording's first take checks this: the textarea's computed outline goes fromauto 1pxtononeonly once the style isoutline-style: none. React Native'sTextStyletype accepts onlysolid | dotted | dashedforoutlineStyle, but react-native-web passesnonethrough to the DOM. The value therefore lives in one web-only constant (noFocusRing) with a comment saying why it is cast, so the cast stays in one place.The cost is small but real: keyboard users now see focus through the pill's border tint, which is softer than the browser's ring. Focus is still visible, but the contrast is lower.
What is not covered
screens.tsxsits inside a styled container the same way and probably shows the same ring. It is left alone to keep this change to the surface that was reported.Field, the website address input) keep the browser ring on purpose, because there it is the only focus indicator.Verification
pnpm --dir apps/mobile typecheckpasses.biome check apps/mobile/src/chat.tsxis clean.apps/mobile/test/*.test.ts).chat.tsxreverted tomain. The computed textarea outline goes fromauto 1pxtonone 1px.